package com.cskaoyan.javase.oop3.innerclazz6.member2;

/**
 * @description: 成员内部类自身特点
 * @author: wuguidong@cskaoyan.onaliyun.com
 **/


import com.cskaoyan.javase.oop3.abstract1.basic2.Demo;
import com.cskaoyan.javase.oop3.interface2.basic2.ITest;

/**
 * 成员内部类的类加载问题:
 * 1,类加载的机制是懒加载,万不得已,不得不加载的时候才会加载该类
 * 2,类加载的时机: 执行该类的main方法,new该类对象
 * 访问该类的静态成员
 * 3,成员内部类的类加载目前来说,只有一种,就是创建成员内部类的对象
 * 4,成员内部类要想创建对象,必须在外围类对象的基础上
 * 成员内部类创建对象,必须依赖外围类对象
 *
 * 思考: 如果我在成员内部类中这样声明:
 * 静态常量不触发类加载的是:
 * 1,基本数据类型
 * 2,String
 * static final OutsideClazz oc = new OutsideClazz();
 * 这种是不行,因为它会触发类加载, 而成员内部类的类加载不会被静态的东西触发
 *
 * > 成员内部类概述
 * - 成员内部类是最普通的内部类，它定义在另一个类的成员位置， 可以看成该类的一个成员
 * - 语法
 *   [访问权限修饰符] class EnclosedClazz{ //外围（普通）类的访问权限修饰符，只有两个，public和缺省
 *   	[访问权限修饰符] class InnerClazz{//内部类访问权限修饰符，有四个，和普通成员一样
 *       }
 *   }
 *
 * 成员内部类自身的特点
 * 1，访问权限修饰符
 * 既然成员内部类是外围类的成员,那么它就有四种访问权限
 * public
 * protected:说明成员内部类也有子类(尝试一下)
 * (default)
 * private
 * 2，成员特点
 * 成员变量:
 * 1,普通成员变量是可以的
 * 2,不能有静态成员,包括静态变量和静态方法
 * 3,允许有静态常量,但是不能是static final修饰的非String引用数据类型
 *
 * 成员内部类中为啥不允许静态?
 * 我查过官方文档,官方也没有明确说
 * 我自己猜的: 设计者认为允许静态 没有太大的好处 反而会有一些麻烦
 *
 * 成员方法
 * 1,没有静态成员方法
 * 2,允许有普通成员方法
 *
 * 构造器
 * 思考:有没有构造器?
 * 和普通类一样,有构造器,是为了给内部类中的普通成员变量赋值的
 *
 * 3，继承和实现(了解,奇思妙想)
 *  1,成员内部类可以像普通类一样去继承,去实现
 *  2,甚至还可以定义内部类 内部接口 去继承实现
 *   甚至可以继承外围类
 *  3,也可以被继承
 *  3,一般来说,不要这么搞,找麻烦
 *
 */
public class OutsideClazz { //外部类
}
class EnclosedClazz{ //外围类

    class InnerClazz extends EnclosedClazz implements InnerInterface{ //内部类
        //成员内部类中定义成员变量
        int a;
        int b = 10;
        //Inner classes cannot have static declarations 内部类无法有静态的声明
        //static int c = 10;
        //static void test(){
        //}
        final int C = 20;
        static final int D = 30; //不触发类加载
        //Inner classes cannot have static declarations
        //static final OutsideClazz oc = new OutsideClazz(); 触发类加载
        static final String E = "111"; //不触发类加载

        public void test(){}

        public InnerClazz(int a, int b) {
            this.a = a;
            this.b = b;
        }

        public InnerClazz() {
        }
    }
    class InnerClazz2{}
    interface InnerInterface{}
}

interface I{}